<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Rust之初：初识 | 人间熙攘，好久不见</title>
    <meta name="generator" content="VuePress 1.7.1">
    <link rel="icon" href="/favicon.ico">
    <script charset="utf-8" crossorigin="anonymous" src="/js/rainyday.js"></script>
    <meta name="description" content="人间熙攘，好久不见~ Magic 的博客">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    <meta name="google-site-verification" content="cFm07VssWCh93-dPrep06FyYb3ST7MIfQnx9B6ZcYsQ">
    
    <link rel="preload" href="/assets/css/0.styles.fe1de732.css" as="style"><link rel="preload" href="/assets/js/app.fe0f04fe.js" as="script"><link rel="preload" href="/assets/js/3.8f0a3ee6.js" as="script"><link rel="preload" href="/assets/js/1.0d4da6ad.js" as="script"><link rel="preload" href="/assets/js/23.8b263173.js" as="script"><link rel="prefetch" href="/assets/js/10.c5719ae1.js"><link rel="prefetch" href="/assets/js/11.22795e1d.js"><link rel="prefetch" href="/assets/js/12.35a1eee1.js"><link rel="prefetch" href="/assets/js/13.ef37c62d.js"><link rel="prefetch" href="/assets/js/14.f36a185b.js"><link rel="prefetch" href="/assets/js/15.06ade84c.js"><link rel="prefetch" href="/assets/js/16.3d06e6fb.js"><link rel="prefetch" href="/assets/js/17.7dd5742a.js"><link rel="prefetch" href="/assets/js/18.7bff1c11.js"><link rel="prefetch" href="/assets/js/19.7bb3239d.js"><link rel="prefetch" href="/assets/js/20.501cb431.js"><link rel="prefetch" href="/assets/js/21.8cfea759.js"><link rel="prefetch" href="/assets/js/22.ef6af803.js"><link rel="prefetch" href="/assets/js/24.dd9f70b8.js"><link rel="prefetch" href="/assets/js/25.4ec78de4.js"><link rel="prefetch" href="/assets/js/26.8e7888cc.js"><link rel="prefetch" href="/assets/js/27.a78de168.js"><link rel="prefetch" href="/assets/js/28.9faf1a01.js"><link rel="prefetch" href="/assets/js/4.a1817f8d.js"><link rel="prefetch" href="/assets/js/5.779f467f.js"><link rel="prefetch" href="/assets/js/6.6a2cdf6b.js"><link rel="prefetch" href="/assets/js/7.ccf4b6c6.js"><link rel="prefetch" href="/assets/js/8.27e71aa7.js"><link rel="prefetch" href="/assets/js/9.6dcd52b0.js">
    <link rel="stylesheet" href="/assets/css/0.styles.fe1de732.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container no-sidebar" data-v-2d5f533b><div data-v-2d5f533b><div id="loader-wrapper" class="loading-wrapper" data-v-d48f4d20 data-v-2d5f533b data-v-2d5f533b><div class="loader-main" data-v-d48f4d20><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div></div> <!----> <!----></div> <div class="password-shadow password-wrapper-out" style="display:none;" data-v-64685f0e data-v-2d5f533b data-v-2d5f533b><h3 class="title" style="display:none;" data-v-64685f0e data-v-64685f0e>人间熙攘，好久不见</h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-64685f0e data-v-64685f0e><input type="password" value="" data-v-64685f0e> <span data-v-64685f0e>Konck! Knock!</span> <button data-v-64685f0e>OK</button></label> <div class="footer" style="display:none;" data-v-64685f0e data-v-64685f0e><span data-v-64685f0e><i class="iconfont reco-theme" data-v-64685f0e></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-64685f0e>vuePress-theme-reco</a></span> <span data-v-64685f0e><i class="iconfont reco-copyright" data-v-64685f0e></i> <a data-v-64685f0e><span data-v-64685f0e>Magic</span>
            
          <span data-v-64685f0e>2017 - </span>
          2022
        </a></span></div></div> <div class="hide" data-v-2d5f533b><header class="navbar" data-v-2d5f533b><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/logo/nav.png" alt="人间熙攘，好久不见" class="logo"> <span class="site-name">人间熙攘，好久不见</span></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">Choose mode</h4> <ul class="color-mode-options"><li class="dark">dark</li><li class="auto active">auto</li><li class="light">light</li></ul></div></div></div> <div class="search-box"><i class="iconfont reco-search"></i> <input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link"><i class="iconfont reco-home"></i>
  Home
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-category"></i>
      Category
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/tools/" class="nav-link"><i class="iconfont undefined"></i>
  tools
</a></li><li class="dropdown-item"><!----> <a href="/categories/Zsh/" class="nav-link"><i class="iconfont undefined"></i>
  Zsh
</a></li><li class="dropdown-item"><!----> <a href="/categories/iTerm2/" class="nav-link"><i class="iconfont undefined"></i>
  iTerm2
</a></li><li class="dropdown-item"><!----> <a href="/categories/Front-end/" class="nav-link"><i class="iconfont undefined"></i>
  Front-end
</a></li><li class="dropdown-item"><!----> <a href="/categories/版本控制-Git/" class="nav-link"><i class="iconfont undefined"></i>
  版本控制-Git
</a></li><li class="dropdown-item"><!----> <a href="/categories/Rust/" class="nav-link"><i class="iconfont undefined"></i>
  Rust
</a></li><li class="dropdown-item"><!----> <a href="/categories/skia-safe/" class="nav-link"><i class="iconfont undefined"></i>
  skia-safe
</a></li><li class="dropdown-item"><!----> <a href="/categories/第三方对接/" class="nav-link"><i class="iconfont undefined"></i>
  第三方对接
</a></li><li class="dropdown-item"><!----> <a href="/categories/Powershell/" class="nav-link"><i class="iconfont undefined"></i>
  Powershell
</a></li><li class="dropdown-item"><!----> <a href="/categories/python/" class="nav-link"><i class="iconfont undefined"></i>
  python
</a></li><li class="dropdown-item"><!----> <a href="/categories/wsl2/" class="nav-link"><i class="iconfont undefined"></i>
  wsl2
</a></li></ul></div></div><div class="nav-item"><a href="/tag/" class="nav-link"><i class="iconfont reco-tag"></i>
  Tags
</a></div><div class="nav-item"><a href="/timeline/" class="nav-link"><i class="iconfont reco-date"></i>
  TimeLine
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont undefined"></i>
      GitHub
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://github.com/magicLaLa/Magic.me" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://github.com/magicLaLa/blog" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  Before
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask" data-v-2d5f533b></div> <aside class="sidebar" data-v-2d5f533b><div class="personal-info-wrapper" data-v-ca798c94 data-v-2d5f533b><img src="/logo/avatar2.gif" alt="author-avatar" class="personal-img" data-v-ca798c94> <h3 class="name" data-v-ca798c94>
    Magic
  </h3> <div class="num" data-v-ca798c94><div data-v-ca798c94><h3 data-v-ca798c94>18</h3> <h6 data-v-ca798c94>文章</h6></div> <div data-v-ca798c94><h3 data-v-ca798c94>11</h3> <h6 data-v-ca798c94>标签</h6></div></div> <hr data-v-ca798c94></div> <nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link"><i class="iconfont reco-home"></i>
  Home
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-category"></i>
      Category
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/tools/" class="nav-link"><i class="iconfont undefined"></i>
  tools
</a></li><li class="dropdown-item"><!----> <a href="/categories/Zsh/" class="nav-link"><i class="iconfont undefined"></i>
  Zsh
</a></li><li class="dropdown-item"><!----> <a href="/categories/iTerm2/" class="nav-link"><i class="iconfont undefined"></i>
  iTerm2
</a></li><li class="dropdown-item"><!----> <a href="/categories/Front-end/" class="nav-link"><i class="iconfont undefined"></i>
  Front-end
</a></li><li class="dropdown-item"><!----> <a href="/categories/版本控制-Git/" class="nav-link"><i class="iconfont undefined"></i>
  版本控制-Git
</a></li><li class="dropdown-item"><!----> <a href="/categories/Rust/" class="nav-link"><i class="iconfont undefined"></i>
  Rust
</a></li><li class="dropdown-item"><!----> <a href="/categories/skia-safe/" class="nav-link"><i class="iconfont undefined"></i>
  skia-safe
</a></li><li class="dropdown-item"><!----> <a href="/categories/第三方对接/" class="nav-link"><i class="iconfont undefined"></i>
  第三方对接
</a></li><li class="dropdown-item"><!----> <a href="/categories/Powershell/" class="nav-link"><i class="iconfont undefined"></i>
  Powershell
</a></li><li class="dropdown-item"><!----> <a href="/categories/python/" class="nav-link"><i class="iconfont undefined"></i>
  python
</a></li><li class="dropdown-item"><!----> <a href="/categories/wsl2/" class="nav-link"><i class="iconfont undefined"></i>
  wsl2
</a></li></ul></div></div><div class="nav-item"><a href="/tag/" class="nav-link"><i class="iconfont reco-tag"></i>
  Tags
</a></div><div class="nav-item"><a href="/timeline/" class="nav-link"><i class="iconfont reco-date"></i>
  TimeLine
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont undefined"></i>
      GitHub
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://github.com/magicLaLa/Magic.me" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://github.com/magicLaLa/blog" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  Before
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav> <!----> </aside> <div class="password-shadow password-wrapper-in" style="display:none;" data-v-64685f0e data-v-2d5f533b><h3 class="title" style="display:none;" data-v-64685f0e data-v-64685f0e>Rust之初：初识</h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-64685f0e data-v-64685f0e><input type="password" value="" data-v-64685f0e> <span data-v-64685f0e>Konck! Knock!</span> <button data-v-64685f0e>OK</button></label> <div class="footer" style="display:none;" data-v-64685f0e data-v-64685f0e><span data-v-64685f0e><i class="iconfont reco-theme" data-v-64685f0e></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-64685f0e>vuePress-theme-reco</a></span> <span data-v-64685f0e><i class="iconfont reco-copyright" data-v-64685f0e></i> <a data-v-64685f0e><span data-v-64685f0e>Magic</span>
            
          <span data-v-64685f0e>2017 - </span>
          2022
        </a></span></div></div> <div data-v-2d5f533b><main class="page"><div class="page-title" style="display:none;"><h1 class="title">Rust之初：初识</h1> <div data-v-3b7f5bdf><i class="iconfont reco-account" data-v-3b7f5bdf><span data-v-3b7f5bdf>Magic</span></i> <i class="iconfont reco-date" data-v-3b7f5bdf><span data-v-3b7f5bdf>2021-03-21</span></i> <i class="iconfont reco-eye" data-v-3b7f5bdf><span id="/Contents/Rust/GetStarted.html" data-flag-title="Your Article Title" class="leancloud-visitors" data-v-3b7f5bdf><a class="leancloud-visitors-count" style="font-size:.9rem;font-weight:normal;color:#999;"></a></span></i> <i class="iconfont reco-tag tags" data-v-3b7f5bdf><span class="tag-item" data-v-3b7f5bdf>Rust</span></i></div></div> <div class="theme-reco-content content__default" style="display:none;"><div class="abstract-box"><h5>Rust Come on</h5> <p><img src="/Abstract/rust/ferris.gif" alt="rust-gif"></p></div> <h2 id="rust-是什么"><a href="#rust-是什么" class="header-anchor">#</a> Rust 是什么？</h2> <p>套用官网的一句话：<strong>一门赋予每个人构建可靠且高效软件能力的语言</strong>。</p> <p>它的语法类似 c++，但是 Rust 能更高效地提供许多功能来保证 <strong>性能</strong> 和 <strong>安全</strong>，而且 Rust <strong>还能在无需使用传统的垃圾收集系统的情况下保证内存的安全性</strong>。</p> <h2 id="可以做什么"><a href="#可以做什么" class="header-anchor">#</a> 可以做什么？</h2> <p>来一张官网的截图：</p> <p><img src="/Abstract/rust/rust-Construct.png" alt="rust-construct"></p> <p>可以看出来能做的事情之多。。。</p> <h2 id="安装"><a href="#安装" class="header-anchor">#</a> 安装</h2> <p>可以根据官网方法安装：<a href="https://www.rust-lang.org/zh-CN/" target="_blank" rel="noopener noreferrer">Rsut<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，mac 可以通过 brew 安装，w10 可以通过 scoop 安装。</p> <h2 id="rust是怎么管理内存安全的"><a href="#rust是怎么管理内存安全的" class="header-anchor">#</a> Rust是怎么管理内存安全的</h2> <p>上文说到 Rust 能在无需使用传统的垃圾收集系统的情况下保证内存的安全性，那它是通过什么来保证的呢？</p> <h3 id="所有权"><a href="#所有权" class="header-anchor">#</a> 所有权</h3> <p>什么是所有权？它是 rust 独有的管理系统（可以使 rust 无需垃圾回收就可以保证内存安全）。它是在编译时完成的，所以并不会带来任何运行时的成本。<br>
rust 默认是在 栈上（已知且固定的大小） 分配内存的，如果需要存储大小未知或者大小可能变化的数据，就要改为存储到 堆 上（会返回位置指针）。</p> <p>规则：</p> <ul><li>Rust 中的每一个值都有一个被称为其 所有者（owner）的变量</li> <li>值有且只有一个所有者</li> <li>当所有者（变量）离开作用域，这个值将被丢弃</li></ul> <p>查看以下代码：</p> <div class="language-rust extra-class"><div class="highlight-lines"><br><div class="highlighted"> </div><div class="highlighted"> </div><div class="highlighted"> </div><br><br><div class="highlighted"> </div><br><br></div><pre class="language-rust"><code><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> str1 <span class="token operator">=</span> <span class="token string">&quot;heelo&quot;</span><span class="token punctuation">;</span>
  <span class="token punctuation">{</span>
      <span class="token keyword">let</span> str2 <span class="token operator">=</span> <span class="token string">&quot;测试&quot;</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// str2 不能使用，因为出了作用域，由编译器完成</span>
  <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">&quot;s is {}, b is {}&quot;</span><span class="token punctuation">,</span> str1<span class="token punctuation">,</span> str2<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>再看一个例子：</li></ul> <div class="language-rust extra-class"><div class="highlight-lines"><br><div class="highlighted"> </div><div class="highlighted"> </div><br><br><br><div class="highlighted"> </div><div class="highlighted"> </div><div class="highlighted"> </div><br></div><pre class="language-rust"><code><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token class-name">Box</span><span class="token punctuation">::</span><span class="token function">new</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 智能指针（储存在 堆上）详见 https://doc.rust-lang.org/book/ch15-01-box.html</span>
    <span class="token function">add_one</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">&quot;{}&quot;</span><span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">fn</span> <span class="token function-definition function">add_one</span><span class="token punctuation">(</span><span class="token keyword">mut</span> num<span class="token punctuation">:</span> <span class="token class-name">Box</span><span class="token operator">&lt;</span><span class="token keyword">i32</span><span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token operator">*</span>num <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// * 解引用</span>
<span class="token punctuation">}</span>
</code></pre></div><p>输出：
<img src="/Abstract/rust/rust-code2.png" alt="rust-code2"></p> <p>在调用 <code>add_one</code> 方法时，变量 <code>x</code> 的所有权转移到了 <code>num</code> 上 （value moved here），当所有权转移时，可变性可以从不可变变成可变的（<a href="https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html" target="_blank" rel="noopener noreferrer">mut<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>），函数完成后，num 的内存将自动释放（出了作用域，会被 drop 掉）。当 <code>println!</code> 再次使用已经没有所有权的变量 <code>x</code> 时，编译器就会报错（如上图所示）。可以尝试 add_one 返回一个 Box 数据，把所有权转移回来，更好的做法时 引入 借用。</p> <div class="language-rust extra-class"><div class="highlight-lines"><br><div class="highlighted"> </div><br><br><div class="highlighted"> </div><br><div class="highlighted"> </div><br><br></div><pre class="language-rust"><code><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token class-name">Box</span><span class="token punctuation">::</span><span class="token function">new</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 智能指针（储存在 堆上）详见： https://doc.rust-lang.org/book/ch15-01-box.html</span>
<span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token function">add_one</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 隐藏（Shadowing）详见：https://kaisery.gitbooks.io/trpl-zh-cn/content/ch03-01-variables-and-mutability.html</span>
<span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">&quot;{}&quot;</span><span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">fn</span> <span class="token function-definition function">add_one</span><span class="token punctuation">(</span><span class="token keyword">mut</span> num<span class="token punctuation">:</span> <span class="token class-name">Box</span><span class="token operator">&lt;</span><span class="token keyword">i32</span><span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Box</span><span class="token operator">&lt;</span><span class="token keyword">i32</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
    <span class="token operator">*</span>num <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">;</span>
    num
<span class="token punctuation">}</span>
</code></pre></div><h3 id="引入-与-借用"><a href="#引入-与-借用" class="header-anchor">#</a> 引入 与 借用</h3> <ul><li>引用：通过 <code>&amp;</code> 使用；</li> <li>借用：通过 <code>*</code> 使用；</li></ul> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> <span class="token keyword">mut</span> vec0 <span class="token operator">=</span> <span class="token class-name">Vec</span><span class="token punctuation">::</span><span class="token function">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    vec0<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">&quot;2&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">let</span> vec1 <span class="token operator">=</span> <span class="token function">fill_vec</span><span class="token punctuation">(</span>vec0<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">&quot;{} has leangth {}&quot;</span><span class="token punctuation">,</span> vec0<span class="token punctuation">,</span> vec1<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">fn</span> <span class="token function-definition function">get_len</span><span class="token punctuation">(</span>vec<span class="token punctuation">:</span> <span class="token class-name">Vec</span><span class="token operator">&lt;</span><span class="token operator">&amp;</span><span class="token keyword">str</span><span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token keyword">usize</span> <span class="token punctuation">{</span>
    vec<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>调用 <code>get_len</code>，传入变量 <code>vec0</code>，这个时候如果直接传入，运行后会报如下错误：</p> <p><img src="/Abstract/rust/rust-yy.png" alt="rust-code2"></p> <p>会告诉我们详细发生了什么（被移动了），就是说在 调用函数结束后 会释放内存，因为在 rust 中 <code>vec0</code> 被移动到了 <code>vec</code> 中，<code>vec0</code> 无效了 （<a href="https://kaisery.gitbooks.io/trpl-zh-cn/content/ch04-01-what-is-ownership.html" target="_blank" rel="noopener noreferrer">所有权<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>），还记得之前 我们提到 离开 作用域 被丢弃了，函数完成 <code>vec</code> 就被清理了，所以 什么都没有了...</p> <p>改动一下 代码如下：</p> <div class="language-rust extra-class"><div class="highlight-lines"><br><div class="highlighted"> </div><div class="highlighted"> </div><br><br><br><div class="highlighted"> </div><br></div><pre class="language-rust"><code><span class="token punctuation">...</span>
<span class="token keyword">let</span> vec1 <span class="token operator">=</span> <span class="token function">fill_vec</span><span class="token punctuation">(</span>vec0<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">get_len</span><span class="token punctuation">(</span>vec<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token class-name">Vec</span><span class="token operator">&lt;</span><span class="token operator">&amp;</span><span class="token keyword">str</span><span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token keyword">usize</span> <span class="token punctuation">{</span>
    vec<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">...</span>
<span class="token comment">// 输出：[&quot;2&quot;] has leangth 1</span>
</code></pre></div><p>借用：就是把 所有权 借用给了 <code>vec</code>，函数完成后，vec 又把 所有权还给了 <code>vec0</code>（这里的引用时不变引用，就是可以 读取 不能 修改，对应的 又 可变引用 <code>&amp;mut</code>），所以运行成功了。</p> <p>特别注意：</p> <ul><li>在任意给定时间，要么 只能有一个可变引用，要么 只能有多个不可变引用。</li> <li>引用必须总是有效的。</li></ul> <h3 id="生命周期-生命周期标记"><a href="#生命周期-生命周期标记" class="header-anchor">#</a> 生命周期：生命周期标记</h3> <p>rust 中生命周期基本跟其他语言类似：声明一个变量，生命周期开始，变量离开作用域，生命周期结束。</p> <p>查看如下代码：</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token punctuation">{</span>
    <span class="token keyword">let</span> r<span class="token punctuation">;</span>

    <span class="token punctuation">{</span>
        <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>
        r <span class="token operator">=</span> <span class="token operator">&amp;</span>x<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">&quot;r: {}&quot;</span><span class="token punctuation">,</span> r<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><img src="/Abstract/rust/rsut-yy1.png" alt="rust-code3"> <br>
这段代码会编译失败，因为引用了一个 无效引用，变量 <code>x</code> 离开作用于了。</p> <p>通过 rust 借用检查器（它比较作用域来确保所有的借用都是有效的），示例如下：</p> <div class="language- extra-class"><div class="highlight-lines"><br><br><br><div class="highlighted"> </div><div class="highlighted"> </div><div class="highlighted"> </div><div class="highlighted"> </div><br><br><br><br></div><pre class="language-text"><code>{
    let r;                // ---------+-- 'a
                          //          |
    {                     //          |
        let x = 5;        // -+-- 'b  |
        r = &amp;x;           //  |       |
    }                     // -+       |
                          //          |
    println!(&quot;r: {}&quot;, r); //          |
}
</code></pre></div><p>可以看到 <code>'b</code> 没有 <code>'a</code>看起来长，就是代表 <code>'b</code> 的生命周期比 <code>'a</code> 的要小：被引用的对象比它的引用者存在的时间更短（悬垂引用）。
更改后代码如下：</p> <div class="language- extra-class"><div class="highlight-lines"><br><br><br><div class="highlighted"> </div><div class="highlighted"> </div><div class="highlighted"> </div><div class="highlighted"> </div><br><br></div><pre class="language-text"><code>{
    let x = 5;            // ----------+-- 'b
                          //           |
    let r = &amp;x;           // --+-- 'a  |
                          //   |       |
    println!(&quot;r: {}&quot;, r); //   |       |
                          // --+       |
}
</code></pre></div><p>rust中生命周期重要的部分是 <strong>生命周期标记</strong> : 通过 <code>'</code> 撇号开头，名称基本都是小写：</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token operator">&amp;</span><span class="token keyword">i32</span>        <span class="token comment">// 引用</span>
<span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token keyword">i32</span>     <span class="token comment">// 带有显式生命周期的引用</span>
<span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token keyword">mut</span> <span class="token keyword">i32</span> <span class="token comment">// 带有显式生命周期的可变引用</span>

</code></pre></div><p>我们可以声明一个带有 生命周期标记的 结构体：</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token attribute attr-name">#[derive(Debug)]</span>
<span class="token keyword">struct</span> <span class="token type-definition class-name">Test</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'c</span><span class="token punctuation">,</span> <span class="token lifetime-annotation symbol">'d</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
    x<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'c</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
    y<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'d</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>

<span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">&quot;hello&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">&quot;world&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">let</span> test <span class="token operator">=</span> <span class="token class-name">Test</span> <span class="token punctuation">{</span> x<span class="token punctuation">:</span> a<span class="token punctuation">,</span> y<span class="token punctuation">:</span> b <span class="token punctuation">}</span><span class="token punctuation">;</span>

    <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">&quot;Test is {:?}&quot;</span><span class="token punctuation">,</span> test<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><img src="/Abstract/rust/live-yy.png" alt="rust-code3"> <br></p> <p>当前结构体 <code>Test</code> 包含两个对 String 的引用，所以需要声明当前域生命周期注解，因为当前结构体有自己的 生存期，需要保证 引用 比当前 结构体 有更长的生命周期，否则就会编译失败，这样就会避免 悬垂引用 的问题。</p> <p>再看一个例子（函数签名中的生命周期注解）：</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">fn</span> <span class="token function-definition function">longest</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'a</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>x<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token keyword">str</span><span class="token punctuation">,</span> y<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token keyword">str</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token keyword">str</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> x<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&gt;</span> y<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        x
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        y
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token string">&quot;hello&quot;</span><span class="token punctuation">;</span>
    <span class="token keyword">let</span> result<span class="token punctuation">;</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">&quot;world&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        result <span class="token operator">=</span> <span class="token function">longest</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">.</span><span class="token function">as_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">&quot;The longest string is {}&quot;</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><img src="/Abstract/rust/lice-yysm.png" alt="rust-code3"> <br></p> <p>可以看到报错信息：<code>b does not live long enough</code>，这是因为 <code>result</code> 生命周期 跟 <code>main</code> 一样长，但是 <code>b</code> 只有在花括号内才是有效的，但是出了花括号作用域就会被释放，所有就无效了。然后根据 <code>longest</code> 函数签名生命周期注解中表示 参数 <code>x</code>、<code>y</code> 的生命周期必须和返回值的 生命周期一样，所以 rust 在编译过程通过 借用检查器 判断出 <code>b</code> 的 生命周期不够长，所以就会报：<code>b does not live long enough</code>。</p> <p>修改代码如下：</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> b<span class="token punctuation">;</span>
<span class="token punctuation">{</span>
    <span class="token punctuation">...</span>
<span class="token punctuation">}</span>
<span class="token punctuation">...</span>
</code></pre></div><p>这样就保证：<code>b</code> 的生命周期和 <code>a</code> 的一样，就可以同归编译输出：<code>The longest string is world</code>。</p> <p>所以 ”显示的指定” (Rust的设计哲学之一) 方便了编译器检查，但是对于 程序猿 有点 繁琐，但是为了安全考虑，我们就欣然接受吧~</p></div> <footer class="page-edit" style="display:none;"><!----> <!----></footer> <!----> <!----> <!----></main> <!----></div></div></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-c6073ba8 data-v-c6073ba8><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-c6073ba8><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-c6073ba8></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-c6073ba8></path></svg></div><div class="kanbanniang" data-v-5775ee02><div class="banniang-container" style="display:;" data-v-5775ee02><div class="messageBox" style="right:68px;bottom:190px;display:none;" data-v-5775ee02>
      欢迎来到 人间熙攘，好久不见
    </div> <div class="operation" style="right:90px;bottom:40px;display:none;" data-v-5775ee02><i class="kbnfont kbn-ban-home ban-home" data-v-5775ee02></i> <i class="kbnfont kbn-ban-message message" data-v-5775ee02></i> <i class="kbnfont kbn-ban-close close" data-v-5775ee02></i> <a target="_blank" href="https://vuepress-theme-reco.recoluan.com/views/plugins/kanbanniang.html" data-v-5775ee02><i class="kbnfont kbn-ban-info info" data-v-5775ee02></i></a> <i class="kbnfont kbn-ban-theme skin" style="display:none;" data-v-5775ee02></i></div> <canvas id="banniang" width="150" height="220" class="live2d" style="right:90px;bottom:-20px;opacity:0.9;" data-v-5775ee02></canvas></div> <div class="showBanNiang" style="display:none;" data-v-5775ee02>
    看板娘
  </div></div><canvas id="vuepress-canvas-cursor"></canvas><canvas id="vuepress-canvas-ribbon"></canvas></div></div>
    <script src="/assets/js/app.fe0f04fe.js" defer></script><script src="/assets/js/3.8f0a3ee6.js" defer></script><script src="/assets/js/1.0d4da6ad.js" defer></script><script src="/assets/js/23.8b263173.js" defer></script>
  </body>
</html>
